package com.ndood.admin.service.system.agent.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ndood.admin.core.constaints.AdminConstaints;
import com.ndood.admin.pojo.comm.dto.DataTableDto;
import com.ndood.admin.pojo.system.agent.AgentPermPo;
import com.ndood.admin.pojo.system.agent.AgentRolePo;
import com.ndood.admin.pojo.system.agent.dto.AgentRoleDto;
import com.ndood.admin.pojo.system.agent.dto.AgentTreeDto;
import com.ndood.admin.pojo.system.agent.query.AgentRoleQuery;
import com.ndood.admin.repository.system.agent.AgentPermRepository;
import com.ndood.admin.repository.system.agent.AgentRoleRepository;
import com.ndood.admin.service.system.agent.SystemAgentRoleService;
import com.ndood.common.base.util.JPAUtil;

/**
 * 角色模块业务类
 * @author ndood
 */
@Service
public class SystemAgentRoleServiceImpl implements SystemAgentRoleService {

	@Autowired
	private AgentRoleRepository agentRoleDao;
	
	@Autowired
	private AgentPermRepository agentPermissionDao;
	
	@Override
	public void addRole(AgentRoleDto dto) throws Exception {
		// Step1: 补充相关默认字段
		dto.setCreateTime(new Date());
		dto.setUpdateTime(new Date());
		
		// Step2: 保存角色
		AgentRolePo po = new AgentRolePo();
		List<Integer> resourceIds = dto.getResourceIds();
		List<AgentPermPo> list = new ArrayList<AgentPermPo>();
		for (Integer resourceId : resourceIds) {
			AgentPermPo temp = new AgentPermPo();
			temp.setId(resourceId);
			list.add(temp);
		}
		JPAUtil.childToFather(dto, po);
		// 设置复杂属性
		po.setPerms(list);
		agentRoleDao.save(po);
	}

	@Override
	public void batchDeleteRole(Integer[] ids) {
		// agentRoleDao.deleteByIdByIds(Arrays.asList(ids));
		for (Integer id : ids) {
			agentRoleDao.deleteById(id);
		}
	}

	@Override
	public void updateRole(AgentRoleDto dto) throws Exception {
		// Step1: 删除旧角色值
		AgentRolePo po = agentRoleDao.findById(dto.getId()).get();
		
		// Step2: 保存新的值
		List<Integer> resourceIds = dto.getResourceIds();
		List<AgentPermPo> list = new ArrayList<AgentPermPo>();
		for (Integer resourceId : resourceIds) {
			AgentPermPo temp = new AgentPermPo();
			temp.setId(resourceId);
			list.add(temp);
		}
		JPAUtil.childToFather(dto, po);
		// 设置特殊属性
		po.setPerms(list);
		agentRoleDao.save(po);
	}
	
	@Override
	public AgentRolePo getRole(Integer id) {
		return agentRoleDao.findById(id).get();
	}

	@Override
	public DataTableDto pageRoleList(AgentRoleQuery query) throws Exception {
		// Step1: 封装查询参数
		Integer pageSize = query.getLimit();
		String keywords = query.getKeywords();
		Integer pageNo = query.getPageNo();
		
		List<Sort.Order> orders = new ArrayList<Sort.Order>();
		Sort.Order order = new Sort.Order(Sort.Direction.ASC, "sort");
		orders.add(order);
		Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.by(orders));

		// Step2: 进行复杂查询
		@SuppressWarnings("serial")
		Page<AgentRolePo> page = agentRoleDao.findAll(new Specification<AgentRolePo>() {
			@Override
			public Predicate toPredicate(Root<AgentRolePo> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
				Predicate p = cb.conjunction();
				if (!StringUtils.isEmpty(keywords)) {
					Predicate temp = cb.or(
						cb.like(root.get("name"), "%" + keywords + "%"),
						cb.like(root.get("desc"), "%" + keywords + "%"));
					p = cb.and(p,temp);
				}
				return p;
			}
		}, pageable);
		
		// Step3: 转换成dto
		List<AgentRoleDto> list = new ArrayList<AgentRoleDto>();
		for (AgentRolePo po : page.getContent()) {
			AgentRoleDto dto = new AgentRoleDto();
			JPAUtil.fatherToChild(po, dto);
			list.add(dto);
		}
		return new DataTableDto(list, page.getTotalElements());
	}

	@Override
	public List<AgentTreeDto> getPermissionTree(Integer roleId) {
		// Step1: 查询出满足条件的资源，并封装成树
		List<AgentPermPo> poList = agentPermissionDao.findByOrderBySort();
		List<AgentTreeDto> dtoList = new ArrayList<AgentTreeDto>();
		for (AgentPermPo po : poList) {
			AgentTreeDto dto = new AgentTreeDto();
			dto.setId(po.getId());
			String pid = po.getParent() == null ? "#" : po.getParent().getId()+"";
			dto.setParent(pid);
			dto.setText(po.getName());
			dto.setType("menu");
			Map<String,Object> state = new HashMap<String,Object>();
			state.put("selected", false);
			dto.setState(state);
			dtoList.add(dto);
		}
		// 如果角色id不存在（添加角色），则直接返回
		if(roleId==null){
			return dtoList;
		}
		
		// Step2: 将所有角色所拥有的资源选中
		AgentRolePo role = agentRoleDao.findById(roleId).get();
		List<AgentPermPo> roList = role.getPerms();
		for (AgentPermPo ro : roList) {
			for (AgentTreeDto dto : dtoList) {
				// 按钮类型才勾选
				if(ro.getId()==dto.getId()&&ro.getType()==3){
					dto.getState().put("selected", true);
				}
			}
		}
		return dtoList;
	}

	@Override
	public List<AgentRoleDto> getRoles() throws Exception {
		// Step1: 查询出满足条件的资源，并封装成树
		List<AgentRolePo> poList = agentRoleDao.findByStatusEqualsOrderBySort(AdminConstaints.STATUS_OK);
		List<AgentRoleDto> dtoList = new ArrayList<AgentRoleDto>();
		for (AgentRolePo po : poList) {
			AgentRoleDto dto = new AgentRoleDto();
			JPAUtil.fatherToChild(po, dto);
			dtoList.add(dto);
		}
		return dtoList;
	}

}
